using Nop.Core;
using Nop.Core.ApiDataModel;
using Nop.Core.Domain.Customers;
using Nop.Services.Authentication;
using Nop.Services.Catalog;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Orders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Http;
using Nop.Core.Domain.Tax;
using Nop.Services.Tax;
using Spotshub.Api.Filter;
using Nop.Core.Domain.Orders;

namespace Spotshub.Api.Controllers.V1
{
    [ExceptionHandler]
    public class OrderController : ApiController
    {
        private readonly IWorkContext _workContext;
        private readonly ICustomerService _customerService;
        private readonly ICustomerRegistrationService _customerRegistrationService;
        private readonly IAuthenticationService _authenticationService;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly ILocalizationService _localizationService;
        private readonly IRegionService _regionService;
        private readonly IOrderService _orderService;
        private readonly IProductAttributeParser _attributeParser;
        private readonly ITaxService _taxService;
        private readonly ICurrencyService _currencyService;
        private readonly IPriceFormatter _priceFormatter;
        private readonly TaxSettings _taxSettings;
        public OrderController(
            IWorkContext workContext,
            ICustomerService customerService,
            ICustomerRegistrationService customerRegistrationService,
            IAuthenticationService authenticationService,
            ICustomerActivityService customerActivityService,
            ILocalizationService localizationService,
            IRegionService regionService,
            IOrderService orderService,
            IProductAttributeParser attributeParser,
            ITaxService taxService,
            ICurrencyService currencyService,
            IPriceFormatter priceFormatter,
            TaxSettings taxSettings)
        {
            this._workContext = workContext;
            this._customerService = customerService;
            this._customerRegistrationService = customerRegistrationService;
            this._authenticationService = authenticationService;
            this._customerActivityService = customerActivityService;
            this._localizationService = localizationService;
            this._regionService = regionService;
            this._orderService = orderService;
            this._attributeParser = attributeParser;
            this._taxService = taxService;
            this._currencyService = currencyService;
            this._priceFormatter = priceFormatter;
            this._taxSettings = taxSettings;
        }

        // Get api/Order/GetOrders
        [HttpGet]
        public IEnumerable<OrderModel> GetOrders(int pageIndex, int pageSize)
        {
            CheckCustomerLogin();
            Nop.Core.Domain.Customers.Customer customer = _workContext.CurrentCustomer;

            List<OrderModel> result = new List<OrderModel>();

            IPagedList<Nop.Core.Domain.Orders.Order> allOrders = this._orderService.GetOrdersByCustomerId(customer.Id, orderKind: null,
                pageIndex: pageIndex, pageSize: pageSize);

            if (allOrders != null && allOrders.Any())
            {
                foreach (var order in allOrders.ToList())
                {
                    if (order.OrderProductVariants != null && order.OrderProductVariants.Any(opv => opv.Quantity > 0))
                    {
                        var orerModel = GenerateAttributes(new OrderModel(order));
                        //if (taxRates.Any())
                        //{
                        //    orerModel.TaxSurcharges = taxRates.Select(tr =>
                        //    {
                        //        var firstOrDefault = allSurchargeTypes.FirstOrDefault(st => st.Id == tr.SurchargeTypeId);
                        //        return firstOrDefault != null ? new TaxSurchargeModel
                        //                                        {
                        //                                            SurchargeType = firstOrDefault.Name,
                        //                                            Amount = tr.Value
                        //                                        } : null;
                        //    }).ToList();
                        //}
                        var taxRates = _taxService.GetSurchargesByOrder(order).ToList().ToTaxes().ToDistinctTypes();
                        var displayTaxRates = _taxSettings.DisplayTaxRates && taxRates.Count > 0;

                        var taxRateList = new List<TaxSurchargeModel>();
                        foreach (var tr in taxRates)
                        {
                            taxRateList.Add(new TaxSurchargeModel
                            {
                                SurchargeType = _priceFormatter.FormatTaxRate(tr),
                                Amount = decimal.Parse(_priceFormatter.FormatPrice(_currencyService.ConvertCurrency(tr.Value, order.CurrencyRate), true, order.CustomerCurrencyCode, false, _workContext.WorkingLanguage).Replace("$",string.Empty))
                            });
                           
                        }
                        orerModel.TaxSurcharges = taxRateList;
                        result.Add(orerModel);
                    }
                }
            }
            return result;
        }

        // Get api/Order/GetOneOrder/{id}
        [HttpGet]
        public Nop.Core.ApiDataModel.OrderModel GetOneOrder(int id)
        {
            CheckCustomerLogin();
            Nop.Core.Domain.Customers.Customer customer = _workContext.CurrentCustomer;

            OrderModel orderResult = null;
            var orders = this._orderService.GetOrdersByCustomerId(customer.Id, orderId: id);
            if (orders != null && orders.Count() > 0)
            {
                orderResult = new OrderModel(orders[0]);
                GenerateAttributes(orderResult);
            }
            else
                orderResult = null;

            return orderResult;
        }

        private OrderModel GenerateAttributes(OrderModel orderResult)
        {
            foreach (var p in orderResult.OrderProduct)
            {
                if (!string.IsNullOrEmpty(p.AttributesXml))
                {
                    p.Attributes = new List<KeyValuePair<string, string>>();
                    var values = this._attributeParser.ParseProductVariantAttributeValues(p.AttributesXml);
                    foreach (var val in values)
                    {
                        p.Attributes.Add(new KeyValuePair<string, string>(val.ProductVariantAttribute.ProductAttribute.Name, val.Name));
                    }
                    p.AttributesXml = string.Empty;
                }
            }
            return orderResult;
        }

        private void CheckCustomerLogin()
        {
            if (_workContext.CurrentCustomer.IsGuest())
                throw new Exception("Anonymous checkout is not allowed");
        }
    }
}
